package com.hanxiaozhang.io.makereactor_1;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.Channel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author hanxinghua
 * @create 2021/8/22
 * @since 1.0.0
 */
public class SelectorThreadGroup {

    private SelectorThread[] sts = null;
    private ServerSocketChannel server = null;
    private AtomicInteger xid = new AtomicInteger(0);

    /**
     * @param num 线程数
     */
    public SelectorThreadGroup(int num) {
        sts = new SelectorThread[num];
        for (int i = 0; i < num; i++) {
            sts[i] = new SelectorThread();
            Thread thread = new Thread(sts[i]);
            thread.start();
        }
    }


    public void bind(int port) {
        try {
            server = ServerSocketChannel.open();
            server.configureBlocking(false);
            server.bind(new InetSocketAddress(port));

            // 注册到那个selector上？
            nextSelector(server);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 无论 是ServerSocket socket 都复用这个方法
     *
     * @param server
     */
    private void nextSelector(Channel server) {
        SelectorThread  st =next();
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) server;
        try {
            // 呼应上 int num = selector.select(100);  被阻塞
            /**
             * st.selector.wakeup(); 应该在register前面，因为register 已经别阻塞住，
             * 验证方法：在register添加st.selector.wakeup(); 然后再添加
             *  System.out.println("register 已经别阻塞住"); 看是否有打印"register 已经别阻塞住"。
             */
            st.selector.wakeup();
            serverSocketChannel.register(st.selector, SelectionKey.OP_ACCEPT);




        } catch (ClosedChannelException e) {
            e.printStackTrace();
        }
    }

    private SelectorThread next() {
        int index = xid.incrementAndGet() % sts.length;
        return sts[index];
    }

}
